package org.jeecg.modules.zcgl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.BigDecimalUtils;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.api.enums.TradeStatusEnum;
import org.jeecg.modules.api.utils.ValidatorUtils;
import org.jeecg.modules.api.vo.param.PaymentParamVo;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.zcgl.entity.CustomerInfo;
import org.jeecg.modules.zcgl.entity.LeaseContractInfo;
import org.jeecg.modules.zcgl.entity.OrderPrestore;
import org.jeecg.modules.zcgl.entity.ReceivablesInfo;
import org.jeecg.modules.zcgl.enums.*;
import org.jeecg.modules.zcgl.mapper.OrderPrestoreMapper;
import org.jeecg.modules.zcgl.service.*;
import org.jeecg.modules.zcgl.util.NoUtils;
import org.jeecg.modules.zcgl.vo.statistical.PersistingRecordsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 预存费用订单信息
 * @Author: jeecg-boot
 * @Date: 2020-12-28
 * @Version: V1.0
 */
@Transactional
@Service
public class OrderPrestoreServiceImpl extends ServiceImpl<OrderPrestoreMapper, OrderPrestore> implements IOrderPrestoreService {

    @Autowired
    private ICustomerBalanceService customerBalanceService;
    @Autowired
    private ILeaseContractInfoService iLeaseContractInfoService;
    @Autowired
    private ICustomerInfoService customerInfoService;
    @Autowired
    private IReceivablesInfoService receivablesInfoService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private ISysDepartService sysDepartService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveAndCustomerBalance(OrderPrestore orderPrestore,LeaseContractInfo leaseContractInfo) {
        boolean saveBool = super.save(orderPrestore);

        //如果支付成功，修改用户余额信息
        if (saveBool &&  orderPrestore.getPayStatus().intValue() == AttentionPayStatusEnum.SUCCESSFUL.getStatus()) {

            //修改用户余额信息
            boolean bool = customerBalanceService.updateBalanceByCustomerIdAndLeaseContractId(orderPrestore.getRentCompanyId(),leaseContractInfo.getId(),
                    orderPrestore.getCustomerId(), orderPrestore.getAmountMoney(), true, orderPrestore.getId(),
                    HandleTypeEnum.DEPOSIT_PAYMENT.getStatus(), "预存费用：" + BigDecimalUtils.formatToThousands(orderPrestore.getAmountMoney()),null);

            if (bool) {
                //查询已计入欠费的该公司的欠费信息
                QueryWrapper<ReceivablesInfo> queryWrapper = new QueryWrapper<>();
                ReceivablesInfo receivablesInfo = new ReceivablesInfo();
                receivablesInfo.setPayStatus(PayStatusEnum.UNPAID.getStatus());
                receivablesInfo.setAmountConfirmation(YesNoEnum.YES.getStatus());
                receivablesInfo.setRentCompanyId(orderPrestore.getRentCompanyId());
                receivablesInfo.setIzOwe(YesNoEnum.YES.getStatus());
                queryWrapper.setEntity(receivablesInfo);
                final String customerSql = QueryGenerator.getCustomerSql(Arrays.asList(orderPrestore.getCustomerId()));
                queryWrapper.and(i -> i.apply(customerSql));
                queryWrapper.lambda().orderByAsc(ReceivablesInfo::getPayStartDate);
                List<ReceivablesInfo> list = receivablesInfoService.list(queryWrapper);
                BigDecimal totalBalance = orderPrestore.getAmountMoney();
                BigDecimal totalDeductionMoney = BigDecimal.ZERO;

//                List<OrderDetails> orderDetailsList = new ArrayList<>();
                CustomerInfo customerInfo = customerInfoService.getById(orderPrestore.getCustomerId());
                //遍历已计入欠费的款项信息
                for (ReceivablesInfo info : list) {

                    BigDecimal deductionMoney = BigDecimal.ZERO;
                    //如果欠费金额小于当前的余额，修改缴费金额和付款状态。
                    if (info.getUnAmountMoney().compareTo(totalBalance) < 1){
                        deductionMoney = info.getUnAmountMoney();
                        totalBalance = totalBalance.subtract(info.getUnAmountMoney()).setScale(2, BigDecimal.ROUND_HALF_UP);
                        info.setUnAmountMoney(BigDecimal.ZERO);
                        info.setPaidAmountMoney(info.getAmountMoney());
                        info.setPayStatus(PayStatusEnum.PAID.getStatus());
                    } else {
                        deductionMoney = totalBalance;
                        totalBalance = BigDecimal.ZERO;
                        info.setUnAmountMoney(info.getUnAmountMoney().subtract(totalBalance).setScale(2, BigDecimal.ROUND_HALF_UP));
                        info.setPaidAmountMoney(info.getPaidAmountMoney().add(totalBalance));
                    }
                    info.setPayType(PayTypeEnum.AUTOMATIC_DEDUCTION.getStatus());
                    info.setPaymentSlipNumber(orderPrestore.getOrderNo());
                    List<String> paymentByList = new ArrayList<>();
                    if (StringUtils.isNotBlank(receivablesInfo.getPaymentBy())){
                        paymentByList.addAll(Arrays.asList(receivablesInfo.getPaymentBy().split(CommonConstant.DEFAULT_SEPARATOR)));
                    }
                    if (!paymentByList.contains(orderPrestore.getCustomerId())){
                        paymentByList.add(orderPrestore.getCustomerId());
                    }
                    info.setPaymentBy(StringUtils.join(paymentByList, CommonConstant.DEFAULT_SEPARATOR));
                    info.setReceiptDate(DateUtils.getDate());
                    receivablesInfoService.updateById(info);

//                    //修改用户余额信息
//                    customerBalanceService.updateBalanceByCustomerIdAndCompanyId(receivablesInfo.getCompanyId(),
//                            receivablesInfo.getCustomerId(), orderPrestore.getAmountMoney(), true, receivablesInfo.getId(),
//                            HandleTypeEnum.RENTAL_FEE.getStatus(), "自动扣费：" + BigDecimalUtils.formatToThousands(deductionMoney));

                    if (StringUtils.isNotBlank(info.getCustomerId())){
                        String[] customerIdAttr = info.getCustomerId().split(CommonConstant.DEFAULT_SEPARATOR);
                        //循环客户ID，如果不是当前客户，退回当前客户付费的部分金额到客户余额
                        for (String customerId : customerIdAttr) {
                            if (!customerId.equalsIgnoreCase(orderPrestore.getCustomerId())){
                                customerBalanceService.updateBalanceByCustomerIdAndLeaseContractId(info.getRentCompanyId(),info.getLeaseContractId(),
                                        customerId, deductionMoney, true, info.getId(),
                                        HandleTypeEnum.RENTAL_RETURN.getStatus(), customerInfo.getName() + "缴费后，退回扣除的费用：" + BigDecimalUtils.formatToThousands(deductionMoney),null);
                            }
                        }
                    }

                    //生成当前扣费的订单详情
                    orderService.creatorOrder(deductionMoney, OrderTypeEnum.AUTOMATIC_DEDUCTION.getStatus(), orderPrestore.getCustomerId(), info);

                    totalDeductionMoney = totalDeductionMoney.add(deductionMoney).setScale(2, BigDecimal.ROUND_HALF_UP);

                    //如果总的余额小于等于0，退出循环，表示当前的预存金额已扣完
                    if (totalBalance.compareTo(BigDecimal.ZERO) < 1){
                        break;
                    }
                }
            }

        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveAndCustomerBalance(PaymentParamVo vo) {

        String validateResult = ValidatorUtils.validateFastStr(vo);
        if (validateResult != null) {
            throw new JeecgBootException(validateResult);
        }
        CustomerInfo customerInfo = customerInfoService.getById(vo.getCustomerId());

        if (customerInfo == null) {
            throw new JeecgBootException("客户信息错误！");
        }
        SysDepart company = sysDepartService.selectCompanyByName(vo.getRecordedCompanyName());
//            String companyId = sysDepartService.selectCompanyIdByName(vo.getRecordedCompanyName());
        if (company == null) {
            throw new JeecgBootException("入账公司信息错误！");
        }

        //查询合同
        LambdaQueryWrapper<LeaseContractInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LeaseContractInfo::getContractNum,vo.getContractNum());
        LeaseContractInfo leaseContractInfo=iLeaseContractInfoService.getOne(lambdaQueryWrapper);

        if(leaseContractInfo==null){
            throw new JeecgBootException("合同信息错误！");
        }

        //查询预存订单号是否已存在，如果存在表示已处理过，直接返回
        QueryWrapper<OrderPrestore> queryWrapper = new QueryWrapper<>();
        OrderPrestore order = new OrderPrestore();
        order.setTransactionId(vo.getTransactionId());
        queryWrapper.setEntity(order);
        Integer num = this.count(queryWrapper);
        if (num != null && num > 0) {
            return true;
        }

        //生成预存订单
        boolean tradeStatus = TradeStatusEnum.SUCCESS.getKey().equalsIgnoreCase(vo.getTradeStatus());
        OrderPrestore orderPrestore = new OrderPrestore();
        BeanUtils.copyProperties(vo, orderPrestore, "amountMoney", "tradeTime");
        orderPrestore.setCompanyId(company.getId());
        orderPrestore.setSysOrgCode(company.getSysOrgCode());
        orderPrestore.setRentCompanyId(company.getId());
        orderPrestore.setAmountMoney(new BigDecimal(vo.getAmountMoney() / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP));
        orderPrestore.setPayType(PayTypeEnum.CCQTGB.getStatus());
        orderPrestore.setPayStatus(tradeStatus ? AttentionPayStatusEnum.SUCCESSFUL.getStatus() : AttentionPayStatusEnum.FAILED.getStatus());
        orderPrestore.setOrderNo(NoUtils.getOrderNo());
        orderPrestore.setTradeTime(DateUtils.parseDate(vo.getTradeTime()));
        return this.saveAndCustomerBalance(orderPrestore,leaseContractInfo);
    }

    @Override
    public IPage<PersistingRecordsVo> queryPersistingRecordsPageList(Page<PersistingRecordsVo> page, QueryWrapper<PersistingRecordsVo> queryWrapper) {
        return baseMapper.queryPersistingRecordsPageList(page,queryWrapper);
    }

    @Override
    public List<PersistingRecordsVo> queryPersistingRecordsPageList(QueryWrapper<PersistingRecordsVo> queryWrapper) {
        return baseMapper.queryPersistingRecordsPageList(queryWrapper);
    }
}
